﻿<!--
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
-->
    
<UserControl 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls"
  xmlns:charting="clr-namespace:Microsoft.Windows.Controls.DataVisualization.Charting;assembly=Microsoft.Windows.Controls.DataVisualization"
  xmlns:samples="clr-namespace:Microsoft.Windows.Controls.Samples"
  xmlns:sys="clr-namespace:System;assembly=mscorlib"
  x:Class="Microsoft.Windows.Controls.Samples.CustomSeriesSample">
    <StackPanel>

        <!-- Basic Examples -->
        <ContentControl Content="Basic Examples" Style="{StaticResource Header}"/>
        <controls:WrapPanel>
            <Grid Style="{StaticResource WrapperStyle}">
                <charting:Chart Title="Constant">
                    <charting:Chart.Series>
                        <charting:ScatterSeries
                          Title="Particulate Levels"
                          ItemsSource="{Binding LevelsInRainfall, Source={StaticResource ParticulateLevel}}"
                          IndependentValueBinding="{Binding Rainfall}"
                          DependentValueBinding="{Binding Particulate}" />
                        <samples:FunctionSeries
                          Function="110"
                          Title="f(x) = 110"
                          LineBrush="Blue"
                          LineThickness="2" />
                    </charting:Chart.Series>
                </charting:Chart>
            </Grid>
            
            <Grid Style="{StaticResource WrapperStyle}">
                <charting:Chart Title="Linear">
                    <charting:Chart.Series>
                        <charting:ScatterSeries
                          Title="Particulate Levels"
                          ItemsSource="{Binding LevelsInRainfall, Source={StaticResource ParticulateLevel}}"
                          IndependentValueBinding="{Binding Rainfall}"
                          DependentValueBinding="{Binding Particulate}" />
                        <samples:FunctionSeries
                          Function="110 + x"
                          Title="f(x) = 110 + x"
                          LineBrush="Green"
                          LineThickness="2" />
                    </charting:Chart.Series>
                </charting:Chart>
            </Grid>
            
            <Grid Style="{StaticResource WrapperStyle}">
                <charting:Chart Title="Quadratic">
                    <charting:Chart.Series>
                        <charting:ScatterSeries
                          Title="Particulate Levels"
                          ItemsSource="{Binding LevelsInRainfall, Source={StaticResource ParticulateLevel}}"
                          IndependentValueBinding="{Binding Rainfall}"
                          DependentValueBinding="{Binding Particulate}" />
                        <samples:FunctionSeries
                          Function="110 + (x - 4)^2"
                          LineBrush="Red"
                          LineThickness="1">
                            <samples:FunctionSeries.Title>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Grid.Row="1" Text="f(x) = 110 + (x - 4)" Margin="0 4 0 0" />
                                    <TextBlock Grid.Column="1" Text="2" FontSize="8" Margin="0"  />
                                </StackPanel>
                            </samples:FunctionSeries.Title>
                        </samples:FunctionSeries>
                    </charting:Chart.Series>
                </charting:Chart>
            </Grid>
            
            <Grid Style="{StaticResource WrapperStyle}">
                <charting:Chart Title="Cubic">
                    <charting:Chart.Series>
                        <charting:ScatterSeries
                          Title="Particulate Levels"
                          ItemsSource="{Binding LevelsInRainfall, Source={StaticResource ParticulateLevel}}"
                          IndependentValueBinding="{Binding Rainfall}"
                          DependentValueBinding="{Binding Particulate}" />
                        <samples:FunctionSeries
                          Function="110 + (x - 4)^3"
                          LineBrush="Black"
                          LineThickness="3">
                            <samples:FunctionSeries.Title>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Grid.Row="1" Text="f(x) = 110 + (x - 4)" Margin="0 4 0 0" />
                                    <TextBlock Grid.Column="1" Text="3" FontSize="8" Margin="0"  />
                                </StackPanel>
                            </samples:FunctionSeries.Title>
                        </samples:FunctionSeries>
                    </charting:Chart.Series>
                </charting:Chart>
            </Grid>
            
            <Grid Style="{StaticResource WrapperStyle}">
                <charting:Chart Title="Inverse">
                    <charting:Chart.Series>
                        <charting:ScatterSeries
                          Title="Particulate Levels"
                          ItemsSource="{Binding LevelsInRainfall, Source={StaticResource ParticulateLevel}}"
                          IndependentValueBinding="{Binding Rainfall}"
                          DependentValueBinding="{Binding Particulate}" />
                        <samples:FunctionSeries
                          Function="110 + 1 / (x - 4)"
                          LineThickness="1">
                            <samples:FunctionSeries.Title>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Grid.Row="1" Text="f(x) = 110 + " VerticalAlignment="Center" />
                                    <StackPanel VerticalAlignment="Center">
                                        <TextBlock Text="1" HorizontalAlignment="Center" />
                                        <Line Stroke="Black" StrokeThickness="1" X1="0" X2="30" Y1="0" Y2="0" />
                                        <TextBlock Text="x - 4" HorizontalAlignment="Center" />
                                    </StackPanel>
                                </StackPanel>
                            </samples:FunctionSeries.Title>
                        </samples:FunctionSeries>
                    </charting:Chart.Series>
                </charting:Chart>
            </Grid>
            
            <Grid Style="{StaticResource WrapperStyle}">
                <charting:Chart x:Name="CustomFunctionChart" Title="Custom Function">
                    <charting:Chart.Series>
                        <charting:ScatterSeries
                          Title="Particulate Levels"
                          ItemsSource="{Binding LevelsInRainfall, Source={StaticResource ParticulateLevel}}"
                          IndependentValueBinding="{Binding Rainfall}"
                          DependentValueBinding="{Binding Particulate}" />
                        <samples:FunctionSeries
                          Title="f(x) = 110 + 3 * Math.Sin(x)"
                          LineThickness="1" />
                    </charting:Chart.Series>
                </charting:Chart>
            </Grid>
        </controls:WrapPanel>
        
        <!-- Regression Scenario -->
        <ContentControl Content="Regression Scenario" Style="{StaticResource Header}"/>
        <Grid Height="500">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBlock HorizontalAlignment="Right" Text="Regression: " />
            <ComboBox
              Grid.Column="1"
              SelectionChanged="OnRegressionTypeChanged"
              HorizontalAlignment="Left">
                <ComboBox.ItemsSource>
                    <controls:ObjectCollection>
                        <sys:String>Linear</sys:String>
                        <sys:String>Quadratic</sys:String>
                        <sys:String>Cubic</sys:String>
                        <sys:String>Quartic</sys:String>
                    </controls:ObjectCollection>
                </ComboBox.ItemsSource>
            </ComboBox>
            <charting:Chart x:Name="ParticulateAnalysis" Grid.Row="1" Grid.ColumnSpan="2" Title="Particulate Level Analysis">
                <charting:Chart.Series>
                    <charting:ScatterSeries
                      Title="Particulate Levels"
                      ItemsSource="{Binding LevelsInRainfall, Source={StaticResource ParticulateLevel}}"
                      IndependentValueBinding="{Binding Rainfall}"
                      DependentValueBinding="{Binding Particulate}" />
                    <samples:FunctionSeries
                      Title="Regression"
                      LineBrush="Blue"
                      LineThickness="2" />
                </charting:Chart.Series>
            </charting:Chart>
        </Grid>
        
        <src:SourceViewer xmlns:src="clr-namespace:Microsoft.Windows.Controls.Samples;assembly=Microsoft.Windows.Controls.Samples.Common" xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <src:SourceFile Path="CustomSeriesSample.xaml">
    <src:SourceFile.Source>
      <sys:String>&lt;!--
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
--&gt;
    
&lt;UserControl 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls"
  xmlns:charting="clr-namespace:Microsoft.Windows.Controls.DataVisualization.Charting;assembly=Microsoft.Windows.Controls.DataVisualization"
  xmlns:samples="clr-namespace:Microsoft.Windows.Controls.Samples"
  xmlns:sys="clr-namespace:System;assembly=mscorlib"
  x:Class="Microsoft.Windows.Controls.Samples.CustomSeriesSample"&gt;
    &lt;StackPanel&gt;

        &lt;!-- Basic Examples --&gt;
        &lt;ContentControl Content="Basic Examples" Style="{StaticResource Header}"/&gt;
        &lt;controls:WrapPanel&gt;
            &lt;Grid Style="{StaticResource WrapperStyle}"&gt;
                &lt;charting:Chart Title="Constant"&gt;
                    &lt;charting:Chart.Series&gt;
                        &lt;charting:ScatterSeries
                          Title="Particulate Levels"
                          ItemsSource="{Binding LevelsInRainfall, Source={StaticResource ParticulateLevel}}"
                          IndependentValueBinding="{Binding Rainfall}"
                          DependentValueBinding="{Binding Particulate}" /&gt;
                        &lt;samples:FunctionSeries
                          Function="110"
                          Title="f(x) = 110"
                          LineBrush="Blue"
                          LineThickness="2" /&gt;
                    &lt;/charting:Chart.Series&gt;
                &lt;/charting:Chart&gt;
            &lt;/Grid&gt;
            
            &lt;Grid Style="{StaticResource WrapperStyle}"&gt;
                &lt;charting:Chart Title="Linear"&gt;
                    &lt;charting:Chart.Series&gt;
                        &lt;charting:ScatterSeries
                          Title="Particulate Levels"
                          ItemsSource="{Binding LevelsInRainfall, Source={StaticResource ParticulateLevel}}"
                          IndependentValueBinding="{Binding Rainfall}"
                          DependentValueBinding="{Binding Particulate}" /&gt;
                        &lt;samples:FunctionSeries
                          Function="110 + x"
                          Title="f(x) = 110 + x"
                          LineBrush="Green"
                          LineThickness="2" /&gt;
                    &lt;/charting:Chart.Series&gt;
                &lt;/charting:Chart&gt;
            &lt;/Grid&gt;
            
            &lt;Grid Style="{StaticResource WrapperStyle}"&gt;
                &lt;charting:Chart Title="Quadratic"&gt;
                    &lt;charting:Chart.Series&gt;
                        &lt;charting:ScatterSeries
                          Title="Particulate Levels"
                          ItemsSource="{Binding LevelsInRainfall, Source={StaticResource ParticulateLevel}}"
                          IndependentValueBinding="{Binding Rainfall}"
                          DependentValueBinding="{Binding Particulate}" /&gt;
                        &lt;samples:FunctionSeries
                          Function="110 + (x - 4)^2"
                          LineBrush="Red"
                          LineThickness="1"&gt;
                            &lt;samples:FunctionSeries.Title&gt;
                                &lt;StackPanel Orientation="Horizontal"&gt;
                                    &lt;TextBlock Grid.Row="1" Text="f(x) = 110 + (x - 4)" Margin="0 4 0 0" /&gt;
                                    &lt;TextBlock Grid.Column="1" Text="2" FontSize="8" Margin="0"  /&gt;
                                &lt;/StackPanel&gt;
                            &lt;/samples:FunctionSeries.Title&gt;
                        &lt;/samples:FunctionSeries&gt;
                    &lt;/charting:Chart.Series&gt;
                &lt;/charting:Chart&gt;
            &lt;/Grid&gt;
            
            &lt;Grid Style="{StaticResource WrapperStyle}"&gt;
                &lt;charting:Chart Title="Cubic"&gt;
                    &lt;charting:Chart.Series&gt;
                        &lt;charting:ScatterSeries
                          Title="Particulate Levels"
                          ItemsSource="{Binding LevelsInRainfall, Source={StaticResource ParticulateLevel}}"
                          IndependentValueBinding="{Binding Rainfall}"
                          DependentValueBinding="{Binding Particulate}" /&gt;
                        &lt;samples:FunctionSeries
                          Function="110 + (x - 4)^3"
                          LineBrush="Black"
                          LineThickness="3"&gt;
                            &lt;samples:FunctionSeries.Title&gt;
                                &lt;StackPanel Orientation="Horizontal"&gt;
                                    &lt;TextBlock Grid.Row="1" Text="f(x) = 110 + (x - 4)" Margin="0 4 0 0" /&gt;
                                    &lt;TextBlock Grid.Column="1" Text="3" FontSize="8" Margin="0"  /&gt;
                                &lt;/StackPanel&gt;
                            &lt;/samples:FunctionSeries.Title&gt;
                        &lt;/samples:FunctionSeries&gt;
                    &lt;/charting:Chart.Series&gt;
                &lt;/charting:Chart&gt;
            &lt;/Grid&gt;
            
            &lt;Grid Style="{StaticResource WrapperStyle}"&gt;
                &lt;charting:Chart Title="Inverse"&gt;
                    &lt;charting:Chart.Series&gt;
                        &lt;charting:ScatterSeries
                          Title="Particulate Levels"
                          ItemsSource="{Binding LevelsInRainfall, Source={StaticResource ParticulateLevel}}"
                          IndependentValueBinding="{Binding Rainfall}"
                          DependentValueBinding="{Binding Particulate}" /&gt;
                        &lt;samples:FunctionSeries
                          Function="110 + 1 / (x - 4)"
                          LineThickness="1"&gt;
                            &lt;samples:FunctionSeries.Title&gt;
                                &lt;StackPanel Orientation="Horizontal"&gt;
                                    &lt;TextBlock Grid.Row="1" Text="f(x) = 110 + " VerticalAlignment="Center" /&gt;
                                    &lt;StackPanel VerticalAlignment="Center"&gt;
                                        &lt;TextBlock Text="1" HorizontalAlignment="Center" /&gt;
                                        &lt;Line Stroke="Black" StrokeThickness="1" X1="0" X2="30" Y1="0" Y2="0" /&gt;
                                        &lt;TextBlock Text="x - 4" HorizontalAlignment="Center" /&gt;
                                    &lt;/StackPanel&gt;
                                &lt;/StackPanel&gt;
                            &lt;/samples:FunctionSeries.Title&gt;
                        &lt;/samples:FunctionSeries&gt;
                    &lt;/charting:Chart.Series&gt;
                &lt;/charting:Chart&gt;
            &lt;/Grid&gt;
            
            &lt;Grid Style="{StaticResource WrapperStyle}"&gt;
                &lt;charting:Chart x:Name="CustomFunctionChart" Title="Custom Function"&gt;
                    &lt;charting:Chart.Series&gt;
                        &lt;charting:ScatterSeries
                          Title="Particulate Levels"
                          ItemsSource="{Binding LevelsInRainfall, Source={StaticResource ParticulateLevel}}"
                          IndependentValueBinding="{Binding Rainfall}"
                          DependentValueBinding="{Binding Particulate}" /&gt;
                        &lt;samples:FunctionSeries
                          Title="f(x) = 110 + 3 * Math.Sin(x)"
                          LineThickness="1" /&gt;
                    &lt;/charting:Chart.Series&gt;
                &lt;/charting:Chart&gt;
            &lt;/Grid&gt;
        &lt;/controls:WrapPanel&gt;
        
        &lt;!-- Regression Scenario --&gt;
        &lt;ContentControl Content="Regression Scenario" Style="{StaticResource Header}"/&gt;
        &lt;Grid Height="500"&gt;
            &lt;Grid.RowDefinitions&gt;
                &lt;RowDefinition Height="Auto" /&gt;
                &lt;RowDefinition /&gt;
            &lt;/Grid.RowDefinitions&gt;
            &lt;Grid.ColumnDefinitions&gt;
                &lt;ColumnDefinition Width="Auto" /&gt;
                &lt;ColumnDefinition /&gt;
            &lt;/Grid.ColumnDefinitions&gt;
            &lt;TextBlock HorizontalAlignment="Right" Text="Regression: " /&gt;
            &lt;ComboBox
              Grid.Column="1"
              SelectionChanged="OnRegressionTypeChanged"
              HorizontalAlignment="Left"&gt;
                &lt;ComboBox.ItemsSource&gt;
                    &lt;controls:ObjectCollection&gt;
                        &lt;sys:String&gt;Linear&lt;/sys:String&gt;
                        &lt;sys:String&gt;Quadratic&lt;/sys:String&gt;
                        &lt;sys:String&gt;Cubic&lt;/sys:String&gt;
                        &lt;sys:String&gt;Quartic&lt;/sys:String&gt;
                    &lt;/controls:ObjectCollection&gt;
                &lt;/ComboBox.ItemsSource&gt;
            &lt;/ComboBox&gt;
            &lt;charting:Chart x:Name="ParticulateAnalysis" Grid.Row="1" Grid.ColumnSpan="2" Title="Particulate Level Analysis"&gt;
                &lt;charting:Chart.Series&gt;
                    &lt;charting:ScatterSeries
                      Title="Particulate Levels"
                      ItemsSource="{Binding LevelsInRainfall, Source={StaticResource ParticulateLevel}}"
                      IndependentValueBinding="{Binding Rainfall}"
                      DependentValueBinding="{Binding Particulate}" /&gt;
                    &lt;samples:FunctionSeries
                      Title="Regression"
                      LineBrush="Blue"
                      LineThickness="2" /&gt;
                &lt;/charting:Chart.Series&gt;
            &lt;/charting:Chart&gt;
        &lt;/Grid&gt;
    &lt;/StackPanel&gt;
&lt;/UserControl&gt;</sys:String>
    </src:SourceFile.Source>
  </src:SourceFile>
  <src:SourceFile Path="CustomSeriesSample.xaml.cs">
    <src:SourceFile.Source>
      <sys:String>// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Microsoft.Windows.Controls.DataVisualization.Charting;
using System.ComponentModel;

namespace Microsoft.Windows.Controls.Samples
{
    /// &lt;summary&gt;
    /// Charting sample demonstrating how to create a custom series.
    /// &lt;/summary&gt;
    [Sample("(2)Custom Series", DifficultyLevel.Advanced)]
    [Category("DataVisualization")]
    public partial class CustomSeriesSample : UserControl
    {
        /// &lt;summary&gt;
        /// Initializes a new instance of the CustomSeriesSample class.
        /// &lt;/summary&gt;
        public CustomSeriesSample()
        {
            InitializeComponent();

            // Use a custom function for a series
            FunctionSeries series = CustomFunctionChart.Series[1] as FunctionSeries;
            series.Function = x =&gt; 110 + 3 * Math.Sin(x);
        }

        /// &lt;summary&gt;
        /// Perform a regression against the particulate levels data.
        /// &lt;/summary&gt;
        /// &lt;param name="sender"&gt;The regression ComboBox.&lt;/param&gt;
        /// &lt;param name="e"&gt;Event arguments.&lt;/param&gt;
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by an event handler in XAML.")]
        [SuppressMessage("Microsoft.Performance", "CA1814:PreferJaggedArraysOverMultidimensional", MessageId = "Body", Justification = "Simplifies the sample.")]
        [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Simplifies the sample.")]
        private void OnRegressionTypeChanged(object sender, SelectionChangedEventArgs e)
        {
            // Get the options and the series
            ComboBox combo = sender as ComboBox;
            if (combo == null || ParticulateAnalysis == null)
            {
                return;
            }
            ScatterSeries dataSeries = ParticulateAnalysis.Series[0] as ScatterSeries;
            FunctionSeries regressionSeries = ParticulateAnalysis.Series[1] as FunctionSeries;
            if (dataSeries == null || regressionSeries == null)
            {
                return;
            }

            // Get the active DataPoints (this assumes the default template for
            // ScatterSeries)
            Canvas plotArea = VisualTreeHelper.GetChild(dataSeries, 0) as Canvas;
            if (plotArea == null)
            {
                return;
            }
            List&lt;DataPoint&gt; activePoints =
                plotArea
                .Children
                .OfType&lt;DataPoint&gt;()
                .ToList();

            // The dimensions were added linearly to the ComboBox
            int dimension = combo.SelectedIndex + 1;

            // Initialize a simple least squares analysis
            int i = 0;
            int j = 0;
            int k = 0;
            double[] y = new double[activePoints.Count];
            double[,] x = new double[activePoints.Count, dimension + 1];
            for (i = 0; i &lt; activePoints.Count; i++)
            {
                DataPoint point = activePoints[i];
                double independentValue = Convert.ToDouble(point.IndependentValue, CultureInfo.InvariantCulture);

                for (j = 0; j &lt;= dimension; j++)
                {
                    x[i, j] = Math.Pow(independentValue, j);
                }

                y[i] = Convert.ToDouble(point.DependentValue, CultureInfo.InvariantCulture);
            }

            // Create the equations
            double[][] matrix = new double[dimension + 1][];
            for (i = 0; i &lt;= dimension; i++)
            {
                // Create the row
                matrix[i] = new double[dimension + 2];

                // indeterminate coefficients
                for (j = 0; j &lt;= dimension; j++)
                {
                    matrix[i][j] = 0.0;
                    for (k = 0; k &lt; activePoints.Count; k++)
                    {
                        matrix[i][j] += x[k, i] * x[k, j];
                    }
                }

                // determinate values
                for (k = 0; k &lt; activePoints.Count; k++)
                {
                    matrix[i][dimension + 1] += x[k, i] * y[k];
                }
            }

            // Convert to row-echelon form
            i = 0;
            j = 0;
            while (i &lt;= dimension &amp;&amp; j &lt;= dimension)
            {
                // Get the pivot in column j starting at row i
                int pivotRow = i;
                for (k = i; k &lt;= dimension; k++)
                {
                    if (Math.Abs(matrix[k][j]) &gt; Math.Abs(matrix[pivotRow][j]))
                    {
                        pivotRow = k;
                    }
                }
                double pivot = matrix[pivotRow][j];

                // If we have a pivot element
                if (pivot != 0)
                {
                    // Swap the current row with the pivot row
                    double[] temp = matrix[i];
                    matrix[i] = matrix[pivotRow];
                    matrix[pivotRow] = temp;
                    pivotRow = i;

                    // Normalize the pivot row to the pivot
                    double c = matrix[i][j];
                    for (k = 0; k &lt;= dimension + 1; k++)
                    {
                        matrix[i][k] /= c;
                    }

                    // Clear out the pivot position from the remaining rows
                    for (k = i + 1; k &lt;= dimension; k++)
                    {
                        c = matrix[k][j];
                        for (int m = i; m &lt;= dimension + 1; m++)
                        {
                            matrix[k][m] -= c * matrix[i][m];
                        }
                    }

                    i++;
                }

                j++;
            }

            // Solve using substitution
            for (i = dimension - 1; i &gt;= 0; i--)
            {
                for (j = dimension; j &gt; i; j--)
                {
                    matrix[i][dimension + 1] -= matrix[i][j] * matrix[j][dimension + 1];
                    matrix[i][j] = 0;
                }
            }

            // Capture the coefficients
            double a0 = matrix[0][dimension + 1];
            double a1 = matrix[1][dimension + 1];
            double a2 = (dimension &gt;= 2) ? matrix[2][dimension + 1] : double.NaN;
            double a3 = (dimension &gt;= 3) ? matrix[3][dimension + 1] : double.NaN;
            double a4 = (dimension == 4) ? matrix[4][dimension + 1] : double.NaN;

            // Create the function
            Func&lt;double, double&gt; function = null;
            switch (dimension)
            {
                case 1:
                    function = z =&gt; a1 * z + a0;
                    break;
                case 2:
                    function = z =&gt; a2 * z * z + a1 * z + a0;
                    break;
                case 3:
                    function = z =&gt; a3 * z * z * z + a2 * z * z + a1 * z + a0;
                    break;
                case 4:
                    function = z =&gt; a4 * z * z * z * z + a3 * z * z * z + a2 * z * z + a1 * z + a0;
                    break;
            }

            // Create the title
            StackPanel title = new StackPanel { Orientation = Orientation.Horizontal };
            title.Children.Add(
                new TextBlock
                {
                    Text = "f(x) = ",
                    Margin = new Thickness(0, 4, 0, 0)
                });

            title.Children.Add(
                new TextBlock
                {
                    Text = a0.ToString("N3", CultureInfo.InvariantCulture),
                    Margin = new Thickness(0, 4, 0, 0)
                });
            AddTitleTerm(title, a1, 1);
            if (dimension &gt;= 2)
            {
                AddTitleTerm(title, a2, 2);
            }
            if (dimension &gt;= 3)
            {
                AddTitleTerm(title, a3, 3);
            }
            if (dimension == 4)
            {
                AddTitleTerm(title, a4, 4);
            }

            // Set the function and the title
            regressionSeries.Function = function;
            regressionSeries.Title = title;
        }

        /// &lt;summary&gt;
        /// Add a term to the title.
        /// &lt;/summary&gt;
        /// &lt;param name="title"&gt;The title container.&lt;/param&gt;
        /// &lt;param name="value"&gt;The value of the term.&lt;/param&gt;
        /// &lt;param name="exponent"&gt;The exponent of the term.&lt;/param&gt;
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by a method called by an event handler in XAML.")]
        private static void AddTitleTerm(StackPanel title, double value, int exponent)
        {
            if (value == 0)
            {
                return;
            }

            title.Children.Add(
                new TextBlock
                {
                    Text = value &gt;= 0 ? " + " : " - ",
                    Margin = new Thickness(0, 4, 0, 0)
                });
            title.Children.Add(
                new TextBlock
                {
                    Text = string.Format(CultureInfo.InvariantCulture, "{0:N3}x", Math.Abs(value)),
                    Margin = new Thickness(0, 4, 0, 0)
                });

            if (exponent &gt; 1)
            {
                title.Children.Add(
                    new TextBlock
                    {
                        Text = exponent.ToString(CultureInfo.InvariantCulture),
                        FontSize = 8
                    });
            }
        }
    }
}</sys:String>
    </src:SourceFile.Source>
  </src:SourceFile>
  <src:SourceFile Path="FunctionSeries.cs">
    <src:SourceFile.Source>
      <sys:String>// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media;
using Microsoft.Windows.Controls.DataVisualization;
using Microsoft.Windows.Controls.DataVisualization.Charting;

namespace Microsoft.Windows.Controls.Samples
{
    /// &lt;summary&gt;
    /// FunctionSeries is used to single variable functions on a chart.
    /// &lt;/summary&gt;
    [TemplatePart(Name = FunctionSeries.PlotAreaName, Type = typeof(Canvas))]
    public sealed partial class FunctionSeries : Series, IRangeAxisInformationProvider
    {
        /// &lt;summary&gt;
        /// The default control template would normally reside in generic.xaml,
        /// but the sample project is an application and doesn't have that file.
        /// We're just putting it here, but a real control project wouldn't.
        /// &lt;/summary&gt;
        private const string DefaultTemplate =
@"&lt;ControlTemplate
  xmlns='http://schemas.microsoft.com/client/2007'
  xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  xmlns:samples='clr-namespace:Microsoft.Windows.Controls.Samples;assembly=Microsoft.Windows.Controls.Samples'
  TargetType='samples:FunctionSeries'&gt;
    &lt;Canvas x:Name='PlotArea'&gt;
        &lt;Path
          Stroke='{TemplateBinding LineBrush}'
          StrokeThickness='{TemplateBinding LineThickness}'
          Data='{TemplateBinding Geometry}' /&gt;
    &lt;/Canvas&gt;
&lt;/ControlTemplate&gt;";

        #region Template Parts
        /// &lt;summary&gt;
        /// Name of the plot area canvas.
        /// &lt;/summary&gt;
        private const string PlotAreaName = "PlotArea";

        /// &lt;summary&gt;
        /// Gets or sets the plot area canvas.
        /// &lt;/summary&gt;
        private Canvas PlotArea { get; set; }
        #endregion Template Parts

        #region public Func&lt;double, double&gt; Function
        /// &lt;summary&gt;
        /// Gets or sets the function to plot.
        /// &lt;/summary&gt;
        [TypeConverter(typeof(SimpleFunctionTypeConverter))]
        public Func&lt;double, double&gt; Function
        {
            get { return GetValue(FunctionProperty) as Func&lt;double, double&gt;; }
            set { SetValue(FunctionProperty, value); }
        }

        /// &lt;summary&gt;
        /// Identifies the Function dependency property.
        /// &lt;/summary&gt;
        public static readonly DependencyProperty FunctionProperty =
            DependencyProperty.Register(
                "Function",
                typeof(Func&lt;double, double&gt;),
                typeof(FunctionSeries),
                new PropertyMetadata(null, OnFunctionPropertyChanged));

        /// &lt;summary&gt;
        /// FunctionProperty property changed handler.
        /// &lt;/summary&gt;
        /// &lt;param name="d"&gt;FunctionSeries that changed its Function.&lt;/param&gt;
        /// &lt;param name="e"&gt;Event arguments.&lt;/param&gt;
        private static void OnFunctionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FunctionSeries source = d as FunctionSeries;
            source.Refresh();
        }
        #endregion public Func&lt;double, double&gt; Function

        #region public Geometry Geometry
        /// &lt;summary&gt;
        /// Gets or sets the geometry of the line object rendering the function.
        /// &lt;/summary&gt;
        public Geometry Geometry
        {
            get { return GetValue(GeometryProperty) as Geometry; }
            set { SetValue(GeometryProperty, value); }
        }

        /// &lt;summary&gt;
        /// Identifies the Geometry dependency property.
        /// &lt;/summary&gt;
        public static readonly DependencyProperty GeometryProperty =
            DependencyProperty.Register(
                "Geometry",
                typeof(Geometry),
                typeof(FunctionSeries),
                new PropertyMetadata(null));
        #endregion public Geometry Geometry

        #region public Brush LineBrush
        /// &lt;summary&gt;
        /// Gets or sets the brush used to plot the function.
        /// &lt;/summary&gt;
        public Brush LineBrush
        {
            get { return GetValue(LineBrushProperty) as Brush; }
            set { SetValue(LineBrushProperty, value); }
        }

        /// &lt;summary&gt;
        /// Identifies the LineBrush dependency property.
        /// &lt;/summary&gt;
        public static readonly DependencyProperty LineBrushProperty =
            DependencyProperty.Register(
                "LineBrush",
                typeof(Brush),
                typeof(FunctionSeries),
                new PropertyMetadata(null, OnLineBrushPropertyChanged));

        /// &lt;summary&gt;
        /// LineBrushProperty property changed handler.
        /// &lt;/summary&gt;
        /// &lt;param name="d"&gt;FunctionSeries that changed its LineBrush.&lt;/param&gt;
        /// &lt;param name="e"&gt;Event arguments.&lt;/param&gt;
        private static void OnLineBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FunctionSeries source = d as FunctionSeries;
            Brush value = e.NewValue as Brush;
            source.LegendItem.DataContext = new ContentControl { Background = value };
        }
        #endregion public Brush LineBrush

        #region public double LineThickness
        /// &lt;summary&gt;
        /// Gets or sets the thickness of the line used to plot the function.
        /// &lt;/summary&gt;
        public double LineThickness
        {
            get { return (double) GetValue(LineThicknessProperty); }
            set { SetValue(LineThicknessProperty, value); }
        }

        /// &lt;summary&gt;
        /// Identifies the LineThickness dependency property.
        /// &lt;/summary&gt;
        public static readonly DependencyProperty LineThicknessProperty =
            DependencyProperty.Register(
                "LineThickness",
                typeof(double),
                typeof(FunctionSeries),
                new PropertyMetadata(1.0));
        #endregion public double LineThickness

        #region private IRangeAxis IndependentAxis
        /// &lt;summary&gt;
        /// Gets or sets the value of the independent axis.
        /// &lt;/summary&gt;
        private IRangeAxis IndependentAxis
        {
            get { return GetValue(IndependentAxisProperty) as IRangeAxis; }
            set { SetValue(IndependentAxisProperty, value); }
        }

        /// &lt;summary&gt;
        /// Identifies the IndependentAxis dependency property.
        /// &lt;/summary&gt;
        private static readonly DependencyProperty IndependentAxisProperty =
            DependencyProperty.Register(
                "IndependentAxis",
                typeof(IRangeAxis),
                typeof(FunctionSeries),
                null);
        #endregion protected IRangeAxis IndependentAxis

        #region private IRangeAxis DependentAxis
        /// &lt;summary&gt;
        /// Gets or sets the value of the dependent axis.
        /// &lt;/summary&gt;
        private IRangeAxis DependentAxis
        {
            get { return GetValue(DependentAxisProperty) as IRangeAxis; }
            set { SetValue(DependentAxisProperty, value); }
        }

        /// &lt;summary&gt;
        /// Identifies the DependentAxis dependency property.
        /// &lt;/summary&gt;
        private static readonly DependencyProperty DependentAxisProperty =
            DependencyProperty.Register(
                "DependentAxis",
                typeof(IRangeAxis),
                typeof(FunctionSeries),
                null);
        #endregion protected IRangeAxis DependentAxis

        /// &lt;summary&gt;
        /// Gets or sets the single chart legend item associated with the
        /// series.
        /// &lt;/summary&gt;
        private LegendItem LegendItem { get; set; }

        /// &lt;summary&gt;
        /// Gets or sets the Geometry used to clip the line to the PlotArea
        /// bounds.
        /// &lt;/summary&gt;
        private RectangleGeometry ClipGeometry { get; set; }

        /// &lt;summary&gt;
        /// Initializes a new instance of the FunctionSeries class.
        /// &lt;/summary&gt;
        public FunctionSeries()
        {
            LegendItem = new LegendItem();
            LegendItems.Add(LegendItem);
            Clip = ClipGeometry = new RectangleGeometry();
            SizeChanged += OnSizeChanged;

            // Explicitly load the default template since the samples project
            // is an application and does not have a generic.xaml file.
            Template = XamlReader.Load(DefaultTemplate) as ControlTemplate;
            LineBrush = new SolidColorBrush(Colors.Purple);
        }

        /// &lt;summary&gt;
        /// Refreshes data from data source and renders the series.
        /// &lt;/summary&gt;
        public override void Refresh()
        {
            if (SeriesHost == null || ActualWidth == 0)
            {
                return;
            }

            // Ensure we have a function to plot
            Func&lt;double, double&gt; function = Function;
            if (function == null)
            {
                return;
            }

            // Ensure we have axes
            IRangeAxis independent = GetAxis(AxisOrientation.Horizontal, IndependentAxis);
            IndependentAxis = independent;
            IRangeAxis dependent = GetAxis(AxisOrientation.Vertical, DependentAxis);
            DependentAxis = dependent;
            if (!independent.Range.HasData)
            {
                return;
            }

            // Create a geometry that matches the function to plot
            PathGeometry path = new PathGeometry();
            PathFigure figure = new PathFigure();

            // Get the range over which we will 
            double start = (double) independent.Range.Minimum;
            double end = (double) independent.Range.Maximum;

            // Adjust the line at each pixel
            double delta = (end - start) / ActualWidth;
            
            // We'll only add a new line segment when the slope is changing
            // between points
            Point last = GetPoint(start, function, independent, dependent);
            figure.StartPoint = last;
            double slope = double.NaN;
            for (double x = start + delta; x &lt;= end; x += delta)
            {
                Point next = GetPoint(x, function, independent, dependent);
                double newSlope = (next.Y - last.Y) / (next.X - last.X);

                if (slope != newSlope)
                {
                    figure.Segments.Add(new LineSegment { Point = last });
                }

                slope = newSlope;
                last = next;
            }
            figure.Segments.Add(new LineSegment { Point = last });

            path.Figures.Add(figure);
            Geometry = path;
        }

        /// &lt;summary&gt;
        /// Get a point in screen coordinates.
        /// &lt;/summary&gt;
        /// &lt;param name="x"&gt;Independent value.&lt;/param&gt;
        /// &lt;param name="function"&gt;The function.&lt;/param&gt;
        /// &lt;param name="independent"&gt;The independent axis.&lt;/param&gt;
        /// &lt;param name="dependent"&gt;The dependent axis.&lt;/param&gt;
        /// &lt;returns&gt;The point in screen coordinates.&lt;/returns&gt;
        private Point GetPoint(double x, Func&lt;double, double&gt; function, IRangeAxis independent, IRangeAxis dependent)
        {
            // Get the dependent value
            double y = double.NaN;
            try
            {
                y = function(x);
            }
            catch (DivideByZeroException)
            {
            }

            // Map the actual values into coordinate values
            return new Point(
                independent.GetPlotAreaCoordinate(x),
                Math.Min(
                    Math.Max(
                        ActualHeight - dependent.GetPlotAreaCoordinate(y),
                        -1),
                    ActualHeight + 1));
        }

        /// &lt;summary&gt;
        /// Get the plot area after loading it from XAML.
        /// &lt;/summary&gt;
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            PlotArea = GetTemplateChild("PlotArea") as Canvas;
        }

        /// &lt;summary&gt;
        /// Updates the visual appearance of all the data points when the size
        /// changes. 
        /// &lt;/summary&gt;
        /// &lt;param name="sender"&gt;The series.&lt;/param&gt;
        /// &lt;param name="e"&gt;Event arguments.&lt;/param&gt;
        private void OnSizeChanged(object sender, SizeChangedEventArgs e)
        {
            // Update the clip geometry
            ClipGeometry.Rect = new Rect(0.0, 0.0, e.NewSize.Width, e.NewSize.Height);

            // Update the PlotArea size and refresh.
            if (PlotArea != null)
            {
                PlotArea.Width = e.NewSize.Width;
                PlotArea.Height = e.NewSize.Height;
                Refresh();
            }
        }

        /// &lt;summary&gt;
        /// Sets all the text the legend items to the title.
        /// &lt;/summary&gt;
        /// &lt;param name="oldValue"&gt;The old title.&lt;/param&gt;
        /// &lt;param name="newValue"&gt;The new title.&lt;/param&gt;
        protected override void OnTitleChanged(object oldValue, object newValue)
        {
            base.OnTitleChanged(oldValue, newValue);
            LegendItem.Content = Title;
        }

        /// &lt;summary&gt;
        /// Get or create a linear numeric axis in the correct dimension.
        /// &lt;/summary&gt;
        /// &lt;param name="orientation"&gt;Dimension of the axis to create.&lt;/param&gt;
        /// &lt;param name="oldAxis"&gt;
        /// Old value of the axis in this dimension.
        /// &lt;/param&gt;
        /// &lt;returns&gt;New value of the axis in this dimension.&lt;/returns&gt;
        private IRangeAxis GetAxis(AxisOrientation orientation, IRangeAxis oldAxis)
        {
            // Check the existing axes for a potential axis
            IRangeAxis axis =
                (from IRangeAxis a in SeriesHost.Axes.OfType&lt;IRangeAxis&gt;()
                 where a.Orientation == orientation
                 select a)
                .FirstOrDefault();

            if (axis == null)
            {
                // Create a new axis if not found
                axis = new LinearAxis
                {
                    Orientation = orientation,
                };
            }

            if (oldAxis != axis)
            {
                // Unregister any existing axis
                if (oldAxis != null)
                {
                    SeriesHost.UnregisterWithAxis(this, oldAxis);
                    oldAxis.Invalidated -= OnAxisInvalidated;
                }
                
                // Register the new axis
                SeriesHost.RegisterWithAxis(this, axis);
                axis.Invalidated += OnAxisInvalidated;
            }

            return axis;
        }

        /// &lt;summary&gt;
        /// Updates the series when the axis is invalidated.
        /// &lt;/summary&gt;
        /// &lt;param name="sender"&gt;The axis that was invalidated.&lt;/param&gt;
        /// &lt;param name="e"&gt;Event arguments.&lt;/param&gt;
        private void OnAxisInvalidated(object sender, EventArgs e)
        {
            if (DependentAxis != null &amp;&amp; IndependentAxis != null)
            {
                Refresh();
            }
        }

        /// &lt;summary&gt;
        /// Ensures that chart and series are kept in a consistent state when a
        /// series is added or removed from a chart. 
        /// &lt;/summary&gt;
        /// &lt;param name="oldValue"&gt;Old chart.&lt;/param&gt;
        /// &lt;param name="newValue"&gt;New chart.&lt;/param&gt;
        protected override void OnSeriesHostPropertyChanged(ISeriesHost oldValue, ISeriesHost newValue)
        {
            IRangeAxis axis = null;

            // Unregister the axes from the old chart
            if (oldValue != null)
            {
                axis = IndependentAxis;
                if (axis != null)
                {
                    oldValue.UnregisterWithAxis(this, axis);
                    IndependentAxis = null;
                }

                axis = DependentAxis;
                if (axis != null)
                {
                    oldValue.UnregisterWithAxis(this, axis);
                    DependentAxis = null;
                }
            }

            // Register the axes with new chart
            if (newValue != null)
            {
                axis = IndependentAxis;
                if (axis != null)
                {
                    newValue.RegisterWithAxis(this, axis);
                }

                axis = DependentAxis;
                if (axis != null)
                {
                    newValue.RegisterWithAxis(this, axis);
                }
            }

            base.OnSeriesHostPropertyChanged(oldValue, newValue);
        }

        /// &lt;summary&gt;
        /// If data is found returns the minimum and maximum dependent numeric
        /// values. 
        /// &lt;/summary&gt;
        /// &lt;param name="rangeAxis"&gt;IRangeAxis that needs the data.&lt;/param&gt;
        /// &lt;returns&gt;
        /// The range of values or empty if no data is present.
        /// &lt;/returns&gt;
        public Range&lt;IComparable&gt; GetActualRange(IRangeAxis rangeAxis)
        {
            // Use an empty range so we only plot over the area used by other
            // axes.
            return new Range&lt;IComparable&gt;();
        }

        /// &lt;summary&gt;
        /// If data is found returns the minimum and maximum dependent numeric
        /// values. 
        /// &lt;/summary&gt;
        /// &lt;param name="rangeAxis"&gt;IRangeAxis that needs the data.&lt;/param&gt;
        /// &lt;returns&gt;
        /// The range of values or empty if no data is present.
        /// &lt;/returns&gt;
        public Range&lt;IComparable&gt; GetDesiredRange(IRangeAxis rangeAxis)
        {
            // Use an empty range so we only plot over the area used by other
            // axes.
            return new Range&lt;IComparable&gt;();
        }
    }
}</sys:String>
    </src:SourceFile.Source>
  </src:SourceFile>
  <src:SourceFile Path="SimpleFunctionTypeConverter.cs">
    <src:SourceFile.Source>
      <sys:String>// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq.Expressions;
using System.Text;

namespace Microsoft.Windows.Controls.Samples
{
    /// &lt;summary&gt;
    /// TypeConverter used for creating single variable functions from simple
    /// arithmetic expressions.
    /// &lt;/summary&gt;
    public class SimpleFunctionTypeConverter : TypeConverter
    {
        /// &lt;summary&gt;
        /// Initializes a new instance of the SimpleFunctionTypeConverter class.
        /// &lt;/summary&gt;
        public SimpleFunctionTypeConverter()
        {
        }

        /// &lt;summary&gt;
        /// Determine whether the sourceType can be converted to a single
        /// variable function.
        /// &lt;/summary&gt;
        /// &lt;param name="context"&gt;Conversion context.&lt;/param&gt;
        /// &lt;param name="sourceType"&gt;The type to convert from.&lt;/param&gt;
        /// &lt;returns&gt;
        /// A value indicating whether the type can be converted.
        /// &lt;/returns&gt;
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return sourceType == typeof(string);
        }

        /// &lt;summary&gt;
        /// Convert the value into a single variable function.
        /// &lt;/summary&gt;
        /// &lt;param name="context"&gt;Conversion context.&lt;/param&gt;
        /// &lt;param name="culture"&gt;Conversion culture.&lt;/param&gt;
        /// &lt;param name="value"&gt;The value to convert.&lt;/param&gt;
        /// &lt;returns&gt;A single variable function.&lt;/returns&gt;
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            Func&lt;double, double&gt; function = null;

            string text = value as string;
            if (!string.IsNullOrEmpty(text))
            {
                function = new Parser(text).Function;
            }

            return function;
        }

        /// &lt;summary&gt;
        /// Defines the type of a token.
        /// &lt;/summary&gt;
        private enum TokenType
        {
            /// &lt;summary&gt;
            /// A numeric value..
            /// &lt;/summary&gt;
            Number,

            /// &lt;summary&gt;
            /// An identifier.
            /// &lt;/summary&gt;
            Identifier,

            /// &lt;summary&gt;
            /// The addition operator.
            /// &lt;/summary&gt;
            Addition,

            /// &lt;summary&gt;
            /// The substraction operator.
            /// &lt;/summary&gt;
            Subtraction,

            /// &lt;summary&gt;
            /// The exponentiation operator.
            /// &lt;/summary&gt;
            Multiplication,

            /// &lt;summary&gt;
            /// The division operator.
            /// &lt;/summary&gt;
            Division,

            /// &lt;summary&gt;
            /// The exponentiation operator.
            /// &lt;/summary&gt;
            Exponentiation,

            /// &lt;summary&gt;
            /// A left parenthesis.
            /// &lt;/summary&gt;
            LeftParenthesis,

            /// &lt;summary&gt;
            /// A right parenthesis.
            /// &lt;/summary&gt;
            RightParenthesis
        }

        /// &lt;summary&gt;
        /// Represents a lexical token.
        /// &lt;/summary&gt;
        private class Token
        {
            /// &lt;summary&gt;
            /// Gets or sets the type of the token.
            /// &lt;/summary&gt;
            public TokenType TokenType { get; set; }

            /// &lt;summary&gt;
            /// Gets or sets the value of a token (for numbers and identifiers).
            /// &lt;/summary&gt;
            public object Value { get; set; }

            /// &lt;summary&gt;
            /// Initializes a new instance of the Token class.
            /// &lt;/summary&gt;
            public Token()
            {
            }
        }

        /// &lt;summary&gt;
        /// Perform lexical analysis of simple expressions.
        /// &lt;/summary&gt;
        private class Lexer
        {
            /// &lt;summary&gt;
            /// Gets or sets the input string to scan.
            /// &lt;/summary&gt;
            internal string Input { get; set; }

            /// &lt;summary&gt;
            /// Gets or sets the current position of the lexer.
            /// &lt;/summary&gt;
            internal int Position { get; set; }

            /// &lt;summary&gt;
            /// Gets a value indicating whether the lexer has room to advance
            /// through the input.
            /// &lt;/summary&gt;
            internal bool CanAdvance
            {
                get { return Position &lt; Input.Length; }
            }

            /// &lt;summary&gt;
            /// Gets the character at the current input position.
            /// &lt;/summary&gt;
            private char Current
            {
                get { return Input[Position]; }
            }

            /// &lt;summary&gt;
            /// Gets or sets the lookahead token.
            /// &lt;/summary&gt;
            private Token Lookahead { get; set; }

            /// &lt;summary&gt;
            /// Initializes a new instance of the Lexer class.
            /// &lt;/summary&gt;
            /// &lt;param name="input"&gt;The input to analyze.&lt;/param&gt;
            public Lexer(string input)
            {
                Debug.Assert(!string.IsNullOrEmpty(input), "input shuould not be null or empty!");
                Input = input;
            }

            /// &lt;summary&gt;
            /// Advance the token to the next input.
            /// &lt;/summary&gt;
            /// &lt;returns&gt;The token that was read.&lt;/returns&gt;
            private Token ReadNext()
            {
                // Eat as much whitespace as possible
                while (CanAdvance &amp;&amp; char.IsWhiteSpace(Current))
                {
                    Position++;
                }

                // Match a literal token
                Token token =
                    MatchLiteral('(', TokenType.LeftParenthesis) ??
                    MatchLiteral(')', TokenType.RightParenthesis) ??
                    MatchLiteral('+', TokenType.Addition) ??
                    MatchLiteral('-', TokenType.Subtraction) ??
                    MatchLiteral('*', TokenType.Multiplication) ??
                    MatchLiteral('/', TokenType.Division) ??
                    MatchLiteral('^', TokenType.Exponentiation);

                // Match identifier or number tokens
                if (token == null)
                {
                    int start = Position;
                    
                    // Try and match identifiers
                    while (CanAdvance &amp;&amp; char.IsLetter(Current))
                    {
                        Position++;
                    }
                    if (start != Position)
                    {
                        token = new Token { TokenType = TokenType.Identifier };
                        token.Value = Input.Substring(start, Position - start);
                    }
                    else
                    {
                        // Try and match numbers
                        while (CanAdvance &amp;&amp; char.IsDigit(Current))
                        {
                            Position++;
                        }
                        if (CanAdvance &amp;&amp; Current == '.')
                        {
                            Position++;
                        }
                        while (CanAdvance &amp;&amp; char.IsDigit(Current))
                        {
                            Position++;
                        }

                        if (start != Position)
                        {
                            token = new Token { TokenType = TokenType.Number };
                            token.Value = double.Parse(Input.Substring(start, Position - start), CultureInfo.InvariantCulture);
                        }
                    }
                }

                if (token != null)
                {
                    return token;
                }
                else if (CanAdvance)
                {
                    throw new FormatException(string.Format(CultureInfo.InvariantCulture, "Unknown token at position {0}!", Position));
                }
                else
                {
                    return null;
                }
            }

            /// &lt;summary&gt;
            /// Match a literal token.
            /// &lt;/summary&gt;
            /// &lt;param name="tokenChar"&gt;Character of the token.&lt;/param&gt;
            /// &lt;param name="tokenType"&gt;The type of the token.&lt;/param&gt;
            /// &lt;returns&gt;The literal token, if matched.&lt;/returns&gt;
            private Token MatchLiteral(char tokenChar, TokenType tokenType)
            {
                if (CanAdvance &amp;&amp; Current == tokenChar)
                {
                    Position++;
                    return new Token { TokenType = tokenType };
                }

                return null;
            }

            /// &lt;summary&gt;
            /// Get the next input token.
            /// &lt;/summary&gt;
            /// &lt;returns&gt;The next input token.&lt;/returns&gt;
            public Token Get()
            {
                Token token = null;
                if (Lookahead != null)
                {
                    token = Lookahead;
                    Lookahead = null;
                }
                else
                {
                    token = ReadNext();
                }
                return token;
            }

            /// &lt;summary&gt;
            /// Peek at the lookahead token.
            /// &lt;/summary&gt;
            /// &lt;returns&gt;The lookahead token.&lt;/returns&gt;
            public Token Peek()
            {
                if (Lookahead == null)
                {
                    Lookahead = ReadNext();
                }
                return Lookahead;
            }
        }

        /// &lt;summary&gt;
        /// Perform syntactic analysis of simple expressions.
        /// &lt;/summary&gt;
        /// &lt;remarks&gt;
        /// The parser uses the following grammar:
        ///    {Expression}
        ///         := {Term} '+' {Expression}
        ///         |  {Term} '-' {Expression}
        ///         |  {Term}
        ///    {Term}
        ///         := {Exponent} '*' {Term}
        ///         |  {Exponent} '/' {Term}
        ///         |  {Exponent}
        ///    {Exponent}
        ///         := {Factor} '^' {Exponent}
        ///         |  {Factor}
        ///    {Factor}
        ///         := {Number}
        ///         |  {Identifier}
        ///         | '(' {Expression} ')'
        /// &lt;/remarks&gt;
        private class Parser
        {
            /// &lt;summary&gt;
            /// Gets or sets the lexer used for lexical analysis.
            /// &lt;/summary&gt;
            private Lexer Lexer { get; set; }

            /// &lt;summary&gt;
            /// Gets or sets the single variable of the function.
            /// &lt;/summary&gt;
            private ParameterExpression Parameter { get; set; }

            /// &lt;summary&gt;
            /// Gets the function created from the input.
            /// &lt;/summary&gt;
            public Func&lt;double, double&gt; Function { get; private set; }

            /// &lt;summary&gt;
            /// Initializes a new instance of the Parser class.
            /// &lt;/summary&gt;
            /// &lt;param name="input"&gt;The input to analyze.&lt;/param&gt;
            public Parser(string input)
            {
                Lexer = new Lexer(input);
                Parse();
            }

            /// &lt;summary&gt;
            /// Parse the input and create a function.
            /// &lt;/summary&gt;
            private void Parse()
            {
                // Build the expression
                Expression expression = GetExpression();

                // Ensure we exhausted the input
                int finalPosition = Lexer.Position;
                Token finalToken = Lexer.Get();
                if (finalToken != null)
                {
                    throw new FormatException(string.Format(CultureInfo.InvariantCulture, "Unexpected token {0} at position {1}!", finalToken.TokenType, finalPosition));
                }

                // Wrap the expression in a function
                Expression&lt;Func&lt;double, double&gt;&gt; functionExpression =
                    Expression.Lambda&lt;Func&lt;double, double&gt;&gt;(
                        expression,
                        Parameter ?? Expression.Parameter(typeof(double), "x"));

                // Compile the expression into a function
                Function = functionExpression.Compile();
            }

            /// &lt;summary&gt;
            /// Read an expression.
            /// &lt;/summary&gt;
            /// &lt;returns&gt;The parsed expression.&lt;/returns&gt;
            private Expression GetExpression()
            {
                Expression term = GetTerm();
                if (TryMatch(TokenType.Addition))
                {
                    Expression expr = GetExpression();
                    return Expression.Add(term, expr);
                }
                else if (TryMatch(TokenType.Subtraction))
                {
                    Expression expr = GetExpression();
                    return Expression.Subtract(term, expr);
                }
                return term;
            }

            /// &lt;summary&gt;
            /// Read a term.
            /// &lt;/summary&gt;
            /// &lt;returns&gt;The parsed term.&lt;/returns&gt;
            private Expression GetTerm()
            {
                Expression exponent = GetExponent();
                if (TryMatch(TokenType.Multiplication))
                {
                    Expression term = GetTerm();
                    return Expression.Multiply(exponent, term);
                }
                else if (TryMatch(TokenType.Division))
                {
                    Expression term = GetTerm();
                    return Expression.Divide(exponent, term);
                }
                return exponent;
            }

            /// &lt;summary&gt;
            /// Read an exponent.
            /// &lt;/summary&gt;
            /// &lt;returns&gt;The parsed exponent.&lt;/returns&gt;
            private Expression GetExponent()
            {
                Expression factor = GetFactor();
                if (TryMatch(TokenType.Exponentiation))
                {
                    Expression power = GetExponent();
                    return Expression.Power(factor, power);
                }
                else
                {
                    return factor;
                }
            }

            /// &lt;summary&gt;
            /// Read a factor.
            /// &lt;/summary&gt;
            /// &lt;returns&gt;The parsed factor.&lt;/returns&gt;
            private Expression GetFactor()
            {
                Token token = Lexer.Get();
                if (token != null)
                {
                    if (token.TokenType == TokenType.Number)
                    {
                        return Expression.Constant(token.Value, typeof(double));
                    }
                    else if (token.TokenType == TokenType.Identifier)
                    {
                        string name = token.Value as string;

                        // Linq expressions use referential equality on
                        // parameters, so we need to use the same instance
                        if (Parameter != null &amp;&amp; Parameter.Name != name)
                        {
                            throw new FormatException("Only single variable functions are supported!");
                        }
                        else if (Parameter == null)
                        {
                            Parameter = Expression.Parameter(typeof(double), name);
                        }
                        return Parameter;
                    }
                    else if (token.TokenType == TokenType.LeftParenthesis)
                    {
                        Expression nested = GetExpression();
                        if (TryMatch(TokenType.RightParenthesis))
                        {
                            return nested;
                        }
                    }
                }

                throw new FormatException(string.Format(CultureInfo.InvariantCulture, "Unexpected token type at position {0}!", Lexer.Position));
            }
            
            /// &lt;summary&gt;
            /// Try to match a token.
            /// &lt;/summary&gt;
            /// &lt;param name="tokenType"&gt;The type of token to match.&lt;/param&gt;
            /// &lt;returns&gt;
            /// A value indicating whether the token was matched.
            /// &lt;/returns&gt;
            private bool TryMatch(TokenType tokenType)
            {
                Token token = Lexer.Peek();
                if (token != null &amp;&amp; token.TokenType == tokenType)
                {
                    Lexer.Get();
                    return true;
                }

                return false;
            }
        }
    }
}</sys:String>
    </src:SourceFile.Source>
  </src:SourceFile>
</src:SourceViewer>
    </StackPanel>
</UserControl>